/**
 * Created by Ben Yip on 2015/3/2.
 */


/*============= a simple test to see all the border of each element===========*/
/*
 Used with the followings:
 
 CSS:
 .test-border {
 border: solid red 1px;
 }
 
 HTML:
 <button id="toggleTestBorder">查看元素边框</button>
 */
var toggleTestBorder = function () {
    var flag = false;

    $("button#toggleTestBorder").click(function () {
        if (!flag) {
            $("*").addClass("test-border");
            flag = true;
        }
        else {
            $("*").removeClass("test-border");
            flag = false;
        }
    });
};

$(function () {
    toggleTestBorder();
});


/*========================================*/
/*=============== tools ==================*/
/*========================================*/

/**
 * test if is undefined
 */
var isUndefined = function (o) {
    return typeof (o) == "undefined";
};

/**
 * see if it's IE
 */
var isIE = function () {
    var userAgent = navigator.userAgent,
            rMsie = /(msie\s|trident.*rv:)([\w.]+)/,
            rFirefox = /(firefox)\/([\w.]+)/,
            rOpera = /(opera).+version\/([\w.]+)/,
            rChrome = /(chrome)\/([\w.]+)/,
            rSafari = /version\/([\w.]+).*(safari)/;
    var browser;
    var version;
    var ua = userAgent.toLowerCase();

    function uaMatch(ua) {
        var match = rMsie.exec(ua);
        if (match != null) {
            return {browser: "IE", version: match[2] || "0"};
        }
        match = rFirefox.exec(ua);
        if (match != null) {
            return {browser: match[1] || "", version: match[2] || "0"};
        }
        match = rOpera.exec(ua);
        if (match != null) {
            return {browser: match[1] || "", version: match[2] || "0"};
        }
        match = rChrome.exec(ua);
        if (match != null) {
            return {browser: match[1] || "", version: match[2] || "0"};
        }
        match = rSafari.exec(ua);
        if (match != null) {
            return {browser: match[2] || "", version: match[1] || "0"};
        }
        if (match != null) {
            return {browser: "", version: "0"};
        }
    }

    var browserMatch = uaMatch(userAgent.toLowerCase());
    if (browserMatch.browser) {
        browser = browserMatch.browser;
        version = browserMatch.version;
    }

    return browserMatch.browser.toLowerCase().match("ie");
};

/**
 * given a number or string represents seconds.
 * return-pattern 12:09:34
 * @param second
 * @returns {string}
 */
var toHHMMSS = function (second) {
    var time = parseFloat(second.toString());
    var hh = Math.floor(time / 3600);
    var mm = Math.floor(time / 60 - hh * 60);
    var ss = Math.round(time - hh * 3600 - mm * 60);
    return (hh === 0 ? "00:" : hh <= 9 ? ("0" + hh + ":") : hh + ":")
            + (mm === 0 ? "00:" : mm + ":")
            + (ss === 0 ? "00:" : ss);
};

/**
 * given a number or string represents seconds.
 * return-pattern 26'12"
 * the minutes would be returned as empty string if equals zero.
 * @param second
 * @returns {string}
 */
var toMMSS = function (second) {
    var time = parseFloat(second.toString());
    var mm = Math.floor(time / 60);
    var ss = Math.round(time - mm * 60);
    return (mm > 9 ? mm + "\'" : mm === 0 ? "" : ("0" + mm + "\'"))
            + (ss <= 9 ? ("0" + ss + "\"") : ss + "\"");
};

/**
 * 计算字符串所占的内存字节数，默认使用UTF-8的编码方式计算，也可制定为UTF-16
 * UTF-8 是一种可变长度的 Unicode 编码格式，使用一至四个字节为每个字符编码
 *
 * 000000 - 00007F(128个代码)      0zzzzzzz(00-7F)                             一个字节
 * 000080 - 0007FF(1920个代码)     110yyyyy(C0-DF) 10zzzzzz(80-BF)             两个字节
 * 000800 - 00D7FF
 00E000 - 00FFFF(61440个代码)    1110xxxx(E0-EF) 10yyyyyy 10zzzzzz           三个字节
 * 010000 - 10FFFF(1048576个代码)  11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz  四个字节
 *
 * 注: Unicode在范围 D800-DFFF 中不存在任何字符
 * {@link http://zh.wikipedia.org/wiki/UTF-8}
 *
 * UTF-16 大部分使用两个字节编码，编码超出 65535 的使用四个字节
 * 000000 - 00FFFF  两个字节
 * 010000 - 10FFFF  四个字节
 *
 * {@link http://zh.wikipedia.org/wiki/UTF-16}
 * @param  {String} str
 * @param  {String} charset utf-8, utf-16
 * @return {Number}
 */
var getByteLength = function (str, charset) {
    var total = 0,
            charCode,
            i,
            len;

    charset = charset ? charset.toLowerCase() : '';
    if (charset === 'utf-16' || charset === 'utf16') {
        for (i = 0, len = str.length; i < len; i++) {
            charCode = str.charCodeAt(i);
            if (charCode <= 0xffff) {
                total += 2;
            } else {
                total += 4;
            }
        }
    } else {
        for (i = 0, len = str.length; i < len; i++) {
            charCode = str.charCodeAt(i);
            if (charCode <= 0x007f) {
                total += 1;
            } else if (charCode <= 0x07ff) {
                total += 2;
            } else if (charCode <= 0xffff) {
                total += 3;
            } else {
                total += 4;
            }
        }
    }
    return total;
};


/**
 * ------------------------------------------------
 * A word counting validating function.
 * (to inform the user about remaining available input length)
 * (disable the submit button when not available)
 * ------------------------------------------------
 *
 * The HTML code in the form container must be included as follows:
 * ...
 * <span class="js-current"></span> / <span class="js-total"></span>
 * ...
 * <button type="submit">发送</button>
 * ...
 *-------------------------------------------------
 * Actually, The formSelector does NOT have to be a form element as long as
 * it contains the previous HTML code.
 *
 * The inputEleSelector is the input element you wanna validate.
 * It can be a <input>, <textarea> or other editable element.
 *
 * The availableLength is the max available length for the input element.
 *
 * The final 2 param is optional.
 *
 * @param formSelector
 * @param inputEleSelector
 * @param availableLength
 * @param normalColor
 * @param warningColor
 */
var wordCountValidate = function (formSelector, inputEleSelector, availableLength, normalColor, warningColor) {
    //set the normal & warning color
    if (isUndefined(normalColor)) {
        normalColor = "green";
    }
    if (isUndefined(warningColor)) {
        warningColor = "red";
    }

    var $form = $(formSelector);
    var $current = $form.find(".js-current").html(0);
    $form.find(".js-total").html(availableLength);

    var $submitBtn = $form.find("button[type='submit']").addClass("disabled");

    $form.find(inputEleSelector).on("input", function () {
        var length = $(this).val().length;
        $current.html(length);

        if (length > availableLength || length == 0) {
            $current.css("font-weight", "bold").css("color", warningColor);
            $submitBtn.addClass("disabled");
        } else {
            $current.css("font-weight", "normal").css("color", normalColor);
            $submitBtn.removeClass("disabled");
        }
    });
};

/**
 * 改进版的wordCountValidate，使得异步请求的也能用，上面的没考虑到这个问题，写得不够灵活。
 */
var wordCountValidateImprove = function (container, inputEleSelector, availableLength, normalColor, warningColor) {
    //set the normal & warning color
    if (isUndefined(normalColor)) {
        normalColor = "green";
    }
    if (isUndefined(warningColor)) {
        warningColor = "red";
    }

    var $container = $(container);
    var $current = $container.find(".js-current").html(0);
    $container.find(".js-total").html(availableLength);

    var $submitBtn = $container.find("button.submit").addClass("disabled");

    $container.find(inputEleSelector).on("input", function () {
        var length = $(this).val().length;
        $current.html(length);

        if (length > availableLength || length == 0) {
            $current.css("font-weight", "bold").css("color", warningColor);
            $submitBtn.addClass("disabled");
        } else {
            $current.css("font-weight", "normal").css("color", normalColor);
            $submitBtn.removeClass("disabled");
        }
    });
};

/*====================================================*/
/*=========== layout or response actions =============*/
/*====================================================*/

/**
 * activate tooltips
 */
$(function () {
    $("[data-toggle='tooltip']").tooltip();
});

/**
 * evoke the masonry layout.
 * This should be called once the document is ready.
 *
 * If there is audio or video,
 * this should be call again when the media is loaded.
 */
var evokeMasonryLayout = function () {
    var $masonry = $(".masonry-container");

    $masonry.masonry({
        itemSelector: ".mason",
        isAnimated: true
    });

    $(window).resize(function () {
        $masonry.masonry("reload");
    });
};

/**
 * when the message box link in the nav bar is clicked, clear the content in the badge.
 */
$(function () {
    $(".js-link-message-box").click(function () {
        $(this).children(".badge").html("");
    });
});


/*================================================================*/
/*========================= message box ==========================*/
/*================================================================*/
/**
 * resize the message box to fit the window.
 */
$(function () {
    var resizeMsgBox = function () {
        var height = $(window).height() - 125;
        var msgBox = $("body.message-box");
        msgBox.find(".navigation").css("height", height);
        msgBox.find(".contacts").css("height", height);
        msgBox.find(".messages").css("height", height);
        msgBox.find(".sending-area").css("height", height);
        msgBox.find(".tips").css("height", height);
    };

    resizeMsgBox();

    $(window).on("resize", function () {
        resizeMsgBox();
    });

    //scroll to bottom of the chat history
    $(".messages").find("ul").scrollTop(99999);
});

/**
 * the actions in message box when switch a chatting target.
 */
var messageReceiveModal = function (loadingImgPath) {
    /**
     * show the delete button on the message when hover,
     * and delete the specific message using AJAX
     */
    var bindDeleteEventHandler = function () {
        $(".content-wrapper").mouseover(function () {
            $(this).children(".delete").show();
        }).mouseleave(function () {
            $(this).children(".delete").hide();
        });

        $(".messages .delete").off().click(function () {
            var me = $(this);
            console.log("用户准备删除一条信息..");
            if (confirm('确认要删除该条信息吗？此操作将不可恢复！')) {
                console.log("确认删除");
                var id = $(this).data("msg-id");
                //todo 这里填上删除信息的URL
                $.post("deleteMessageURL", {id: id}, function (data) {
                    if (data == "success") {
                        me.closest(".msg").remove();
                        var msgAmount = $("#msg-amount");
                        msgAmount.html(msgAmount.html().trim() - 1);
                    } else {
                        alert("删除失败，请重试。");
                    }
                });
                console.log("完成删除");
            } else {
                console.log("取消删除。");
            }
        });
    };

    //todo 此处调用仅用于静态页面测试。
    //bindDeleteEventHandler();

    /**
     * 用于封装一条消息
     * @param id {int}
     * @param content {string}
     * @param time {string}
     * @param sent {int} 1:自己发的, 0:对方发的(即自己接收)
     * @constructor
     */
    function Message(id, content, time, sent) {
        this.id = id;
        this.content = content;
        this.time = time;
        this.sent = sent;
    }

    //用于拼接信息的DOM
    var msgDOM1_left = '<li class="msg left"> <div class="content-wrapper"> <div class="arrow"></div> <div class="delete" data-msg-id="';
    var msgDOM1_right = '<li class="msg right"> <div class="content-wrapper"> <div class="arrow"></div> <div class="delete" data-msg-id="';
    var msgDOM2 = '">&times;</div> <div class="content">';
    var msgDOM3 = '</div> <div class="time">';
    var msgDOM4 = '</div> </div></li>';

    //todo 这里需要填上正确的动态路径
    //加载信息时显示的等待画面
    var loadingDOM = '<li class="loading"><img src="' + loadingImgPath + '" alt="加载中"/><div class="mask"></div></li>';

    $(".contacts .people").click(function () {
        //show the loading masks
        var msgContainer = $(".messages").find("ul");
        msgContainer.empty().append(loadingDOM);
        //mask the contact-list also.
        $(".contacts").prepend('<div class="loading-mask"></div>');

        //switch .active when select different contacts in contact list
        if (!$(this).is(".active")) {
            $(this).addClass("active").siblings().removeClass("active");
        }

        //remove the number in the badge when corresponding contact is selected
        var me = $(this);
        setTimeout(function () {
            me.children(".badge").html("");
        }, 1000);

        //get the corresponding chat history using AJAX and re-render the page
        var chatTargetID = $(this).data("contact-id");
        var chatTargetType = $(this).data("contact-type");


        //todo 模拟请求成功
//        setTimeout(function () {
        $.post("getMessage", {id: chatTargetID, type: chatTargetType}, function (data) {

            try {
                console.log(data);
                var jsonData = data;
                console.log(jsonData);

                //模拟服务器返回的JSON数据
//                var jsonData = [
//                    {id: 0, content: "我是内容0", time: "2015-6-5 13:36:30", sent: 0},
//                    {id: 1, content: "我是内容1", time: "2015-6-5 13:36:31", sent: 1},
//                    {id: 2, content: "我是内容2", time: "2015-6-5 13:36:32", sent: 1},
//                    {id: 3, content: "我是内容3", time: "2015-6-5 13:36:33", sent: 0},
//                    {id: 4, content: "我是内容4", time: "2015-6-5 13:36:34", sent: 1},
//                    {id: 5, content: "我是内容5", time: "2015-6-5 13:36:35", sent: 0},
//                    {id: 6, content: "我是内容6", time: "2015-6-5 13:36:36", sent: 1},
//                    {id: 7, content: "我是内容7", time: "2015-6-5 13:36:37", sent: 0},
//                    {id: 8, content: "我是内容8", time: "2015-6-5 13:36:38", sent: 0}
//                ];

                //populate into an array.
                var msgList = [];
                for (var i = 0, len = jsonData.length; i < len; i++) {
                    msgList.push(new Message(jsonData[i].id, jsonData[i].content, jsonData[i].time, jsonData[i].sent));
                }

                //amend the info in  msg list header.
                $("#msg-amount").text(msgList.length);
                $("#chat-target").text(me.find(".name").text());

                //append messages to the document.
                msgContainer.empty();
                for (i = 0, len = msgList.length; i < len; i++) {
                    var msgDomString = "";
                    if (msgList[i].sent == 0)
                        msgDomString += msgDOM1_left;
                    else
                        msgDomString += msgDOM1_right;
                    msgDomString += msgList[i].id + msgDOM2 + msgList[i].content + msgDOM3 + msgList[i].time + msgDOM4;
                    msgContainer.append(msgDomString);
                }

                //scroll to the bottom
                msgContainer.scrollTop(99999);

                //amend the targetID info in the instant msg-reply
                $("#instant-reply-id").data("id", chatTargetID);
                $("#instant-reply-type").data("type", chatTargetType);
                $("#instant-reply-name").data("name", me.find(".name").text());

                //call the delete event handler
                bindDeleteEventHandler();

                //remove the mask in contact list
                $(".contacts").find(".loading-mask").remove();
            } catch (e) {
                alert("加载信息失败，请重试。");
                console.log(e.type);
                console.log(e.message);
                return false;
            }

        });

//        }, 1000);
    });

    /**
     * when the document is ready, load the dialog list of the first contact automatically.
     */
    $(".contacts .people:first").trigger("click");

    /**
     * the instant-msg-reply via AJAX
     */
    $("#instant-reply-submit-btn").click(function () {
        var me = $(this).addClass("disabled");

        var id = $("#instant-reply-id").data("id");
        var type = $("#instant-reply-type").data("type");
        var name = $("#instant-reply-name").data("name");
        var content = $("#instant-reply-content").val();

        console.log("准备发送即时信息...");
        console.log("id=" + id);
        console.log("type=" + type);
        console.log("name=" + name);
        console.log("content=" + content);

        $.post("postMessage", {
            "id": id,
            "type": type,
            "name": name,
            "content": content
        }, function (data) {
            try {
                if (data != "error") {
                    var msgDomString = "";
                    if (data.sent == 0)
                        msgDomString += msgDOM1_left;
                    else
                        msgDomString += msgDOM1_right;
                    msgDomString += data.id + msgDOM2 + data.content + msgDOM3 + data.time + msgDOM4;
                    $(".messages").find("ul").append(msgDomString).scrollTop(99999);
                    bindDeleteEventHandler();
                    var msgAmount = $("#msg-amount");
                    msgAmount.html(msgAmount.html().trim() - 0 + 1);
                }
            } catch (e) {
                console.log(e.type);
                console.log(e.message);
                alert("发送失败，请重试");
            } finally {
                me.removeClass("disabled");
                $("#instant-reply-content").val("");
            }
        });
    });
    
    $(window).on("keydown",function(e){
        if(e.ctrlKey && e.which === 13){
            $("#instant-reply-submit-btn").trigger("click");
        }
    });
};

/**
 * Form validation for message sending page.
 * included: check if the contact exists when character radio box is selected.
 */
$(function () {
    var receiverInput = $("#receiver");
    var radioLabels = $("#new-message").find("label.btn");
    var feedbackModal = $("#msg-send-feedback-modal");
    var modalFeedbackContent = feedbackModal.find(".modal-body").find("p");

    //改变收件人ID时，清除收件人的身份选择
    receiverInput.on("input", function () {
        radioLabels.removeClass("active").children("input").prop("checked", false);
    });

    //选择接受人类型后发起AJAX验证身份请求
    radioLabels.click(function (e) {
        feedbackModal.on('hidden.bs.modal', function () {
            receiverInput.focus().select();
        });

        var id = receiverInput.val().trim();

        if (isNaN(id) || id == "") {
            modalFeedbackContent.text("请正确输入收件人ID（纯数字）");
            feedbackModal.modal("show");
            e.stopPropagation();
            e.preventDefault();
            return false;
        } else {
            var character = $(this).children("input").val();
            console.log("准备发起AJAX请求验证收件人： id = " + id + " ，身份 = " + character);

            //延时，模拟服务器返回数据
//            setTimeout(function () {
            //todo AJAX
            $.post("checkNumber", {id: id, type: character}, function (data) {
//                alert(data)
//                var data = "success";
                if (data != "error") {
//                    alert(data);
                    $("#receiver-name").val(data);
                    modalFeedbackContent.text("该收件人存在，请继续填写信息内容。");
                    feedbackModal.modal("show").on('hidden.bs.modal', function () {
                        $("#content").focus();
                    });
                } else {
                    modalFeedbackContent.text("该收件人不存在，请重新填写收件人信息。");
                    feedbackModal.modal("show");
                    receiverInput.val("");
                    radioLabels.removeClass("active").children("input").prop("checked", false);
                }
            });
//            }, 100);

        }
    });

    //todo 测试radio的选中情况，无实际用途。
    $("#test").click(function () {
        var msgSendContainer = $("#new-message");
        var str = "";
        msgSendContainer.find("label.btn").each(function () {
            str += $(this).children("input").prop("checked") + " ";
        });
        msgSendContainer.find("#feedback").find("#foooooooooo").text(str);
    });
});


/*================================================================================*/

/**
 * Word count validation.
 */
$(function () {
    //for messageBox Receiving page
    wordCountValidateImprove(".msg-reply", "textarea", 250, "#999", "red");
    //for messageBox Sending page
    wordCountValidate("#new-message", "textarea", 1000);
    //for password alteration modal dialog.
    wordCountValidate("#password-alteration-modal", "#new-psw", 20);
    //for appliance of pushing off defense
    wordCountValidate("#delay-reason", "textarea", 1000);
    //for delayCheck of tch
    wordCountValidate("#delay-check-tch", "textarea", 1000);
    //for delayApply of stu
    wordCountValidate("#form-delay-apply","textarea",1000);
});

/**
 * the assignment info page should be opened in a new popup window.
 */
$(function () {
    $(".assignmentInfo-link").click(function () {
        var topLocation = (window.screen.height - 600) * .5;
        var leftLocation = (window.screen.width - 1024) * .5;
        window.open($(this).data("url"), "",
                "height=600, " +
                "width=1024," +
                "top=" + topLocation + "," +
                "left=" + leftLocation + "," +
                "location=no," +
                "menubar=no," +
                "resizable=yes," +
                "scrollbars=yes");
    });
});

/**
 * new password confirm validation before submit
 */
$(function () {
    $("#password-alteration-modal").submit(function () {
        if ($("#new-psw").val() !== $("#new-psw-confirm").val()) {
            alert("Sorry，新密码两次输入不一致，请检查后重新提交。");
            console.log("不一致呢");
            return false;
        } else {
            console.log("233");
        }
    });
});

/**
 * 查询筛选器的展开/折叠按钮文案toggle上下箭头图形文字
 */
$(function () {
    $(".js-filter-collapser").click(function () {
        var $arrow = $(this).find(".glyphicon");
        if ($arrow.is(".glyphicon-chevron-down")) {
            $arrow.removeClass().addClass("glyphicon glyphicon-chevron-up");
        } else {
            $arrow.removeClass().addClass("glyphicon glyphicon-chevron-down");
        }
        //$(this).find(".glyphicon")
        //    .removeClass("glyphicon-chevron-down")
        //    .addClass("glyphicon-chevron-up");
    })
});

/**
 * 表格中工具按钮的显示与隐藏
 */
$(function () {
    $(".table-cell-hover-tool").hover(function () {
        if ($(this).find(".tool").length !== 0) {
            $(this).find(".content").hide();
            $(this).find(".tool").show();
        }
    }, function () {
        $(this).find(".content").show();
        $(this).find(".tool").hide();
    });
});

/**
 * 在select中选择完后，在给定的input域中填入相应的value
 *
 * @param sSelector
 *      select的选择器
 * @param iSelector
 *      input域的选择器
 */
var select2input = function (sSelector, iSelector) {
    $(sSelector).change(function () {
        $(iSelector).val($(this).val());
    });
};


/**
 * 表格中的全选按钮：
 * 按下时全选所有checkbox，再次按下时取消全选
 */
$(function () {
    $(".js-select-all").click(function () {
        var $cb = $(this).parentsUntil("table").parent().find("input[type='checkbox']");
        if ($(this).data("checked") == false) {
            $(this).html("取消").data("checked", true);
            $cb.each(function () {
                $(this).prop("checked", true);
            });
        } else if ($(this).data("checked") == true) {
            $(this).html("全选").data("checked", false);
            $cb.each(function () {
                $(this).prop("checked", false);
            });
        }
    });
});

function getDeptData(imgpath) {
    // var result;
    //todo 实际AJAX封装
    $.post("getDepts", function (data) {
        //alert(data.length);
        try {
            //result = data;//JSON.parse(data);
            getAndRenderDeptTree(data, imgpath);
        } catch (e) {
            alert("加载机构信息失败，请刷新重试。");
            return false;
        }
    });
    //return result;
}

/**
 * 使用AJAX获取机构列表，然后在前端生成机构树。
 *
 * 附：dTree的add方法api
 * #  Name     Type    Description
 * 1  id       Number  Unique identity number.
 * 2  pid      Number  Number referring to the parent node. The value for the root node has to be -1.
 * 3  name     String  Text label for the node.
 * 4  url      String  Url for the node.
 * 5  title    String  Title for the node.
 * 6  target   String  Target for the node.
 * 7  icon     String  Image file to use as the icon. Uses default if not specified.
 * 8  iconOpen String  Image file to use as the open icon. Uses default if not specified.
 * 9  open     Boolean Is the node open.
 */
var getAndRenderDeptTree = function (data, imgpath) {
    /**
     * 用于封装的构造方法
     *
     * @param id {int}
     * @param pid {int}
     * @param name {string}
     */
    function treeNode(id, pid, name) {
        this.id = id;
        this.pid = pid;
        this.name = name;
    }
    //模拟服务器返回的JSON数据
    var jsonData = data;
    console.log(data);
//    var jsonData = [
//        {id: 9999, pid: -1, name: "所有机构"},
//        {id: 0, pid: 9999, name: "数学与信息学院"},
//        {id: 1, pid: 0, name: "计算机专业"},
//        {id: 2, pid: 1, name: "计算机1班"},
//        {id: 3, pid: 1, name: "计算机2班"},
//        {id: 4, pid: 1, name: "计算机3班"},
//        {id: 5, pid: 0, name: "软件专业"},
//        {id: 6, pid: 5, name: "软件1班"},
//        {id: 7, pid: 5, name: "软件2班"}
//    ];

    var deptList = [];
    for (var i = 0, len = jsonData.length; i < len; i++) {
        deptList.push(new treeNode(jsonData[i].id, jsonData[i].pid, jsonData[i].name));
    }

    console.log(deptList);

    //构造并生成树
    //todo dTree 已经改造过，可以传入图片路径作为第二个参数。
    tree = new dTree("tree", imgpath);
    for (i = 0, len = deptList.length; i < len; i++) {
        tree.add(deptList[i].id, deptList[i].pid, deptList[i].name, "javascript:void(0)");
    }
    var treeContainer = $("#dept-tree");
    treeContainer.html(tree.toString());

    //为每个节点添加工具按钮，关联机构ID
    var toolsDom1 = '<span class="tools"><button class="edit btn btn-xs btn-primary" data-dept-id="';
    var toolsDom2 = '" data-toggle="modal" data-target="#dept-edit"><span class="glyphicon glyphicon-pencil"></span></button><button class="new btn btn-xs btn-success" data-dept-id="';
    var toolsDom3 = '" data-toggle="modal" data-target="#dept-new"><span class="glyphicon glyphicon-plus"></span></button><button class="remove btn btn-xs btn-danger"  data-dept-id="';
    var toolsDom4 = '" data-toggle="modal" data-target="#dept-remove"><span class="glyphicon glyphicon-trash"></span></button></span>';
    var deptID;
    treeContainer.find(".dTreeNode").each(function () {
        for (i = 0, len = deptList.length; i < len; i++) {
            if ($.trim(deptList[i].name) == $(this).find("a.node").html()) {
                deptID = deptList[i].id;
                break;
            } else {
                deptID = 9999; //这一一个为了前端显示而构造的总根结点，后台接受到以这个为pid的机构创建请求时，即创建一个无父机构的机构
            }
        }
        $(this).append(toolsDom1 + deptID + toolsDom2 + deptID + toolsDom3 + deptID + toolsDom4).hover(function () {
            $(this).find(".tools").toggleClass("show");
        });
    });

    //去除根结点的编辑与删除按钮（此根结点为前端显示的根结点，无关数据库）
    treeContainer.children(".dtree").children(".dTreeNode").find(".edit, .remove").remove();

    //绑定工具按钮事情驱动
    treeContainer.find(".btn.edit").click(function () {
        var deptID = $(this).data("dept-id");
        var deptName = $(this).closest(".dTreeNode").find("a.node").text();
        console.log("准备编辑机构： name = " + deptName + ", id = " + deptID);
        $("#dept-id-edit").val(deptID);
        $("#dept-name-edit").val(deptName);
    });
    treeContainer.find(".btn.new").click(function () {
        var deptID = $(this).data("dept-id");
        var deptName = $(this).closest(".dTreeNode").find("a.node").text();
        console.log("准备新增机构： parentName = " + deptName + ", pid = " + deptID);
        if (deptID == 9999)
            deptName = "无（即不从属于任何机构）";
        $("#dept-name-parent").html(deptName);
        $("#dept-pid").val(deptID);
    });
    treeContainer.find(".btn.remove").click(function () {
        var deptID = $(this).data("dept-id");
        var deptName = $(this).closest(".dTreeNode").find("a.node").text();
        console.log("准备删除机构： name = " + deptName + ", id = " + deptID);
        $("#removing-dept-name").html(deptName);
        $("#dept-id-remove").val(deptID);
    });

    //展开树
    tree.openAll();

    //使得模态框中的输入框获取焦点
    $("#dept-edit").on('shown.bs.modal', function () {
        $('#dept-name-edit').focus().select();
    });
    $("#dept-new").on('shown.bs.modal', function () {
        $('#dept-name-new').focus();
    });


};

/**
 * 用于机构查询：
 * 机构信息一开始全部装载入页面，用户输入机构名称后，
 * 直接正则过滤查询条件，隐藏掉页面上的不对应的元素。
 */
var deptSearch = function () {
    $("#dept-sch-input").focus(function () {
        $(this).select();
    });

    var deptList = $("#dept-list").find("tr");

    $("#dept-search").click(function () {
        deptList.each(function () {
            $(this).show();
        });

        var keyword = $("#dept-sch-input").val().trim();
        if (keyword == "")
            return false;

        deptList.each(function () {
            if ($(this).children("td:first-child").text().trim().indexOf(keyword) === -1) {
                $(this).hide();
            }
        });
    });
};

/**
 * 其他使用优化
 */
$(function () {
    //模态框激活时自动获取焦点
    $("#newNotice").on('shown.bs.modal', function () {
        $('#title').focus();
    });
    $("#new-tch-single").on('shown.bs.modal', function () {
        $('#add_workno').focus();
    });
    $("#alter-tch-info").on('shown.bs.modal', function () {
        $('#newTNo').focus();
    });
    $("#new-stu-single").on('shown.bs.modal', function () {
        $('#id').focus();
    });
    $("#alter-stu-info").on('shown.bs.modal', function () {
        $('#new_stuNo').focus();
    });
    $("#delay-apply").on('shown.bs.modal', function () {
        $('#reason').focus();
    });

    //分页器自动获得焦点
    $(".pagination input").hover(function () {
        $(this).focus().select();
    });

});

/**
 * automatically hide feedback message
 */
$(function hideAlert() {
    var alert_message = $(".alert.feedback-float");
    var timeoutID = setTimeout(function () {
        alert_message.fadeOut();
    }, 1500);
    alert_message.mouseenter(function () {
        clearTimeout(timeoutID);
    }).mouseleave(function () {
        $(this).fadeOut();
    });
});
